package com.weilx959.spt.core.component;

import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXTextField;
import com.jfoenix.validation.base.ValidatorBase;
import com.weilx959.spt.core.StageContext;
import com.weilx959.spt.core.constants.CommonConstants;
import com.weilx959.spt.core.utils.FXMLUtil;
import com.weilx959.spt.core.utils.Try;
import javafx.beans.NamedArg;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.stage.FileChooser;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class FileChooserFormItemControl extends ValidatorFormItemControl<String> {
    private static final String XML = "/assets/fxml/component/file-chooser-form-control.fxml";

    @FXML
    private Label labelControl;

    @FXML
    private JFXTextField fileNameControl;

    @FXML
    private JFXButton browseControl;

    @Setter
    @Getter
    private String fileTypeDesc;

    @Setter
    @Getter
    private String[] fileTypes;

    public FileChooserFormItemControl() {
        super();
        fileTypeDesc = "所有文件";
        fileTypes = new String[] {"*.*"};
        initialize();
    }

    public FileChooserFormItemControl(@NamedArg(value = "label", defaultValue = "label")String label,
                                      @NamedArg(value = "key", defaultValue = "key")String key,
                                      @NamedArg(value = "value")String value,
                                      @NamedArg(value = "fileTypeDesc", defaultValue = "所有文件") String fileTypeDesc,
                                      @NamedArg(value = "fileTypes", defaultValue = "*.*") String fileTypes) {
        super();
        setLabel(label);
        setKey(key);
        setValue(value);
        this.fileTypeDesc = fileTypeDesc;
        this.fileTypes = StringUtils.split(fileTypes, CommonConstants.Symbol.COMMA);
        initialize();
    }

    @Override
    public boolean isModified() {
        return !StringUtils.equals(getValue(), oldValue);
    }

    @Override
    public Try<String> validate() {
        return Try.of(() -> {
            if (!fileNameControl.validate()) {
                throw new IllegalStateException(fileNameControl.getActiveValidator().getMessage());
            }
        });
    }

    @Override
    public void addValidator(ValidatorBase... validators) {
        fileNameControl.setValidators(validators);
    }

    private void initialize() {
        // load
        FXMLUtil.loadControl(this, XML);
    }

    /**
     * 打开文件选择器
     *
     * @param event 事件
     */
    @FXML
    private void openFileChooserAction(ActionEvent event) {
        event.consume();
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("请选择" + getLabel());
        fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(fileTypeDesc, fileTypes));
        var file = fileChooser.showOpenDialog(StageContext.get());

        if (Objects.isNull(file) || file.isDirectory() || !file.exists()) {
            fileNameControl.setText("");
        } else {
            fileNameControl.setText(file.getAbsolutePath());
        }
    }

    // builder
    public static FileChooserFormItemControlBuilder builder() {
        return new FileChooserFormItemControlBuilder();
    }

    public static class FileChooserFormItemControlBuilder
        extends ValidatorFormItemControlBuilder<String, FileChooserFormItemControl, FileChooserFormItemControlBuilder> {
        private String fileTypeDesc = "所有文件";
        private List<String> fileTypes = List.of("*.*");

        public FileChooserFormItemControlBuilder fileTypeDesc(String fileTypeDesc) {
            this.fileTypeDesc = fileTypeDesc;
            return this;
        }

        public FileChooserFormItemControlBuilder fileTypes(String... fileTypes) {
            List<String> fileTypeList = new ArrayList<>();

            for (String fileType : fileTypes) {
                if (StringUtils.isNotBlank(fileType)) {
                    fileTypeList.add(fileType);
                }
            }
            this.fileTypes = fileTypeList;
            return this;
        }

        public FileChooserFormItemControlBuilder fileType(String fileType) {
            if (Objects.isNull(fileTypes)) {
                fileTypes = new ArrayList<>();
            }
            fileTypes.add(fileType);
            return this;
        }

        @Override
        public FileChooserFormItemControl build() {
            FileChooserFormItemControl control = super.build();
            control.setFileTypeDesc(fileTypeDesc);

            if (CollectionUtils.isNotEmpty(fileTypes)) {
                control.setFileTypes(fileTypes.toArray(new String[0]));
            }
            return control;
        }

        @Override
        protected FileChooserFormItemControl newFormItemControl() {
            return new FileChooserFormItemControl();
        }

        @Override
        protected FileChooserFormItemControlBuilder self() {
            return this;
        }
    }
}
